#include "app_bluetooth.h"
#include "thirdparty/log.c/log.h"
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>

static unsigned char bluetooth_buffer[64];
static int bluetooth_buffer_len = 0;
static const unsigned char fix_header[] = {0xF1, 0xDD};

/**
 * @brief 通过识别特定的头部，将缓存中的数据移动到头部
 *
 * @return int -1表示没有找到特定头部 0表示找到ACK 1表示找到固定头部
 *
 */
static int app_bluetooth_seekHeader()
{
    int result = -1, i;
    for (i = 0; i < bluetooth_buffer_len - 3; i++)
    {
        if (memcmp(bluetooth_buffer + i, "OK", 2) == 0)
        {
            result = 0;
            break;
        }
        else if (memcmp(bluetooth_buffer + i, fix_header, 2) == 0)
        {
            result = 1;
            break;
        }
    }
    if (result >= 0)
    {
        bluetooth_buffer_len -= i;
        memcpy(bluetooth_buffer, bluetooth_buffer + i, bluetooth_buffer_len);
    }

    return result;
}

static int app_bluetooth_waitACK(Device *device)
{
    char buf[10];
    bzero(buf, 10);
    int len = read(device->fd, buf, 10);
    if (len == 0)
    {
        return -1;
    }
    if (buf[0] != 'O' || buf[1] != 'K')
    {
        return -1;
    }
    return 0;
}

int app_bluetooth_exists(Device *device)
{
    if (write(device->fd, "AT\r\n", 4) < 0)
    {
        return -1;
    }
    return app_bluetooth_waitACK(device);
}

int app_bluetooth_reset(Device *device)
{
    if (write(device->fd, "AT+RESET\r\n", 10) < 0)
    {
        return -1;
    }
    return app_bluetooth_waitACK(device);
}

int app_bluetooth_setBaudRate(Device *device, BluetoothBaudRate baud_rate)
{
    char buf[10];
    memcpy(buf, "AT+BAUD8\r\n", 10);
    buf[7] = baud_rate;
    if (write(device->fd, buf, 10) < 0)
    {
        return -1;
    }
    return app_bluetooth_waitACK(device);
}

int app_bluetooth_setNetId(Device *device, char *net_id)
{
    char buf[14];
    memcpy(buf, "AT+NETID", 8);
    memcpy(buf + 8, net_id, 4);
    memcpy(buf + 12, "\r\n", 2);
    if (write(device->fd, buf, 14) < 0)
    {
        return -1;
    }
    if (app_bluetooth_waitACK(device) < 0)
    {
        return -1;
    }

    memcpy(buf, "AT+MADDR0001\r\n", 14);
    if (write(device->fd, buf, 14) < 0)
    {
        return -1;
    }
    return app_bluetooth_waitACK(device);
}

void app_bluetooth_postRecv(Device *device, void *ptr, int *len)
{
    // 将收到的数据拷贝到缓冲区
    memcpy(bluetooth_buffer + bluetooth_buffer_len, ptr, *len);
    bluetooth_buffer_len += *len;
    // 查询固定头部，确定新的数据帧的起始位置
    // 如果拼接缓存的长度不足4个字节，那么不做处理，将*len设置为0
    if (bluetooth_buffer_len < 4)
    {
        *len = 0;
        log_trace("Not a complete data frame, skip");
        return;
    }
    int header_result = app_bluetooth_seekHeader();
    if (header_result < 0)
    {
        *len = 0;
        log_trace("Can not find valid header");
        return;
    }
    if (header_result == 0)
    {
        // 处理ACK
        *len = 0;
        log_trace("Received ACK");
        device->last_write_ts = 0;
        bluetooth_buffer_len -= 4;
        memcpy(bluetooth_buffer, bluetooth_buffer + 4, bluetooth_buffer_len);
        return;
    }

    // 处理数据帧
    if (bluetooth_buffer_len < 3 + bluetooth_buffer[2])
    {
        // 拼接缓存区不是完整的数据帧，不做处理，将*len设置为0
        *len = 0;
        log_trace("Not a complete data frame, skip");
        return;
    }

    *len = bluetooth_buffer[2];
    unsigned char *temp = ptr;
    temp[0] = 2;
    temp[1] = bluetooth_buffer[2] - 4;
    // 拷贝远端ID
    memcpy(temp + 2, bluetooth_buffer + 3, temp[0]);
    // 拷贝数据
    memcpy(temp + 2 + temp[0], bluetooth_buffer + 3 + temp[0] + 2, temp[1]);
    // 从缓存区中移除完整数据帧
    bluetooth_buffer_len -= 3 + *len;
    memcpy(bluetooth_buffer, bluetooth_buffer + 3 + *len, bluetooth_buffer_len);
}

// 将message的16进制数据处理成蓝牙芯片适用的16进制数据
void app_bluetooth_preSend(Device *device, void *ptr, int *p_len)
{
    unsigned char buf[24], *original = ptr;

    // 首先判断消息长度是否合法, 不合法直接忽略
    if (original[0] + original[1] + 2 != *p_len || original[0] != 2 || original[1] > 12)
    {
        *p_len = 0;
        return;
    }

    // 最终消息的长度应该为"AT+MESH\0" + ID + MSG + "\r\n"
    *p_len = 8 + original[0] + original[1] + 2;
    memcpy(buf, "AT+MESH", 8);
    memcpy(buf + 8, original + 2, original[0] + original[1]);
    memcpy(buf + 8 + original[0] + original[1], "\r\n", 2);
    memcpy(ptr, buf, *p_len);
}
